﻿using System;
using System.Collections.Generic;
using System.Text;

using Spring.Context;
using Spring.Context.Support;

using Yawf.Core.Exceptions;
using Yawf.Core.Logs;

namespace Yawf.Core {
	public class Initializer {
		// Static members are lazily initialized.
    // .NET guarantees thread safety for static initialization
		private static readonly object padlock = new object();
		private static Initializer _instance = null;

		private IApplicationContext springContext = null;

		/// <summary>
		/// Empty private constructor, cause this is a sigleton
		/// </summary>
		private Initializer() {
			// Initialize Spring 
			try {
				Log.DebugMessage(this.GetType(),"Starting initializing Spring Context");
				springContext = ContextRegistry.GetContext();
				Log.DebugMessage(this.GetType(), "Spring Context loaded");
			} catch (Exception e) {
				Log.WarnMessage(typeof(Initializer),"Error while initializing Spring Context, Exception " + e);
				throw new YawfException("Error while initializing Spring Context",e);
			}
    }

		/// <summary>
		/// Gets singelton instance
		/// </summary>
		public static Initializer Instance { 
			get{
				lock (padlock) {
					if (_instance == null) {
						_instance = new Initializer();
					}
				}
				return _instance;
			}
		}

		/// <summary>
		/// Spring Context
		/// </summary>
		public IApplicationContext SpringContext { get { return springContext; } }

		/// <summary>
		/// Gets an object from Spring
		/// </summary>
		/// <param name="name"></param>
		/// <returns></returns>
		public Object GetObject(String name) {
			Object bean = null;

			try {
				if (springContext == null) {
					throw new YawfException("Spring Context no definido ");
				}
				bean = springContext.GetObject(name);
			} catch (Exception e) {
				throw new YawfException("Error al obtener spring object " + name, e);
			}
			
			return bean;
		}									// GetObject


		/// <summary>
		/// Gets an object from Spring
		/// </summary>
		/// <param name="name">Name of object</param>
		/// <param name="defaultValue">Default value if object does no exists</param>
		/// <returns></returns>
		public Object GetObject(String name,Object defaultValue) {
			Object bean = null;

			try {
				if (springContext == null) {
					return defaultValue;
				}
				bean = springContext.GetObject(name);
			} catch {
				// Quitly return default value
				bean = defaultValue;
			}

			return bean;
		}									// GetObject

		/// <summary>
		/// Checks if an object exists 
		/// </summary>
		/// <param name="name">Name of object in Spring Context</param>
		/// <returns>true if object exists false otherwise</returns>
		public bool ContainsObject(String name) {
			return springContext != null && springContext.ContainsObject(name);
		}

	}								// Class 
}
